package com.c5p1ng.route.util;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 本地ip获取工具类
 *
 * @author csp
 */
public class LocalIpUtil {
    public static Set<String> priorityLocal = Arrays.asList("eth", "en").stream().collect(Collectors.toSet());
    private static volatile String localIp = null;
    private static Set<String> localIps = new HashSet();

    public LocalIpUtil() {
    }

    public static String getLocalIp() {
        if (localIp != null) {
            return localIp;
        } else {
            try {
                Enumeration<NetworkInterface> allNetInterface = NetworkInterface.getNetworkInterfaces();
                List<NetworkInterface> list = new ArrayList();

                String priority;
                while(allNetInterface.hasMoreElements()) {
                    NetworkInterface e = allNetInterface.nextElement();

                    for(Enumeration<InetAddress> address = e.getInetAddresses(); address.hasMoreElements(); localIps.add(priority)) {
                        InetAddress add = address.nextElement();
                        priority = add.getHostAddress();
                        if (priority.contains("%")) {
                            priority = priority.substring(0, priority.indexOf("%"));
                        }
                    }

                    list.add(e);
                }

                Iterator interfaceIterator = list.iterator();

                NetworkInterface networkInterface;
                while(interfaceIterator.hasNext()) {
                    networkInterface = (NetworkInterface)interfaceIterator.next();
                    Iterator natIterator = priorityLocal.iterator();

                    while(natIterator.hasNext()) {
                        priority = (String)natIterator.next();
                        if (networkInterface.getName().startsWith(priority) && getLocalIpInner(networkInterface)) {
                            return localIp;
                        }
                    }
                }

                interfaceIterator = list.iterator();

                do {
                    if (!interfaceIterator.hasNext()) {
                        return null;
                    }
                    networkInterface = (NetworkInterface)interfaceIterator.next();
                } while(!getLocalIpInner(networkInterface));
                return localIp;
            } catch (SocketException var6) {
                throw new RuntimeException(var6);
            }
        }
    }

    private static boolean getLocalIpInner(NetworkInterface networkInterface) {
        Enumeration<InetAddress> address = networkInterface.getInetAddresses();

        while(address.hasMoreElements()) {
            InetAddress ip = address.nextElement();
            if (ip instanceof Inet4Address) {
                String hostAddress = ip.getHostAddress();
                if (hostAddress != null && hostAddress.trim().length() != 0 && !hostAddress.startsWith("127")) {
                    localIp = hostAddress;
                    return true;
                }
            }
        }

        return false;
    }
}
